﻿using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;

namespace LevelEditor.Document
{
    public class XmlSerializableDictionary<TKey, TValue> : Dictionary<TKey, TValue>, IXmlSerializable
    {
        /// <summary>
        /// Inherit all the functionality we need from dictionary
        /// </summary>
        #region Constructors

        public XmlSerializableDictionary() : base() { }

        public XmlSerializableDictionary(IDictionary<TKey, TValue> dictionary)
            : base(dictionary) { }

        public XmlSerializableDictionary(IEqualityComparer<TKey> comparer)
            : base(comparer) { }

        public XmlSerializableDictionary(int capacity)
            : base(capacity) { }

        public XmlSerializableDictionary(IDictionary<TKey, TValue> dictionary
            , IEqualityComparer<TKey> comparer)
            : base(dictionary, comparer) { }

        public XmlSerializableDictionary(int capacity
            , IEqualityComparer<TKey> comparer)
            : base(capacity, comparer) { }

        public XmlSerializableDictionary(SerializationInfo info
            , StreamingContext context)
            : base(info, context) { }

        #endregion

        #region XML Methods

        // don't need this; return null
        public XmlSchema GetSchema() { return null; }

        public void ReadXml(XmlReader reader)
        {
            XmlSerializer keySerial = new XmlSerializer(typeof(TKey));
            XmlSerializer valueSerial = new XmlSerializer(typeof(TValue));
            bool empty = reader.IsEmptyElement;
            reader.Read();
            if (empty) return;
            while (reader.NodeType != XmlNodeType.EndElement)
            {
                reader.ReadStartElement("Item");
                reader.ReadStartElement("Key");
                TKey key = (TKey)keySerial.Deserialize(reader);
                reader.ReadEndElement();
                reader.ReadStartElement("Value");
                TValue value = (TValue)valueSerial.Deserialize(reader);
                reader.ReadEndElement();
                Add(key, value);
                reader.ReadEndElement();
                reader.MoveToContent();
            }
            reader.ReadEndElement();
        }

        public void WriteXml(XmlWriter writer)
        {
            XmlSerializer keySerial = new XmlSerializer(typeof(TKey));
            XmlSerializer valueSerial = new XmlSerializer(typeof(TValue));
            foreach (TKey key in Keys)
            {
                writer.WriteStartElement("Item");
                writer.WriteStartElement("Key");
                keySerial.Serialize(writer, key);
                writer.WriteEndElement();
                writer.WriteStartElement("Value");
                valueSerial.Serialize(writer, this[key]);
                writer.WriteEndElement();
                writer.WriteEndElement();
            }
        }

        #endregion
    }
}
